home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xarchie-2.0.9 / xarchie.c < prev    next >
C/C++ Source or Header  |  1995-06-18  |  22KB  |  718 lines

  1. /*
  2.  * xarchie : An X browser interface to Archie
  3.  *
  4.  * George Ferguson, ferguson@cs.rochester.edu, 2 Nov 1991.
  5.  * Version 2.0: 23 Apr 1993.
  6.  * 28 Apr 1993: Change default host to "archie.sura.net(1526)".
  7.  * 13 May 1993: Apply icon resources to realToplevel.
  8.  *        Don't call XtMapWidget() or -iconic is ignored.
  9.  *        Apply tilde expansion to initial value of ftpLocalDir resource.
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <X11/Intrinsic.h>
  14. #include <X11/StringDefs.h>
  15. #include <X11/Shell.h>    
  16. #include <X11/Xaw/Form.h>
  17. #include <X11/Xaw/Label.h>
  18. #include <X11/Xaw/Command.h>
  19. #include <X11/Xaw/Paned.h>
  20. #include <X11/Xaw/Viewport.h>
  21. #include <X11/Xaw/AsciiText.h>
  22. #include <X11/Xaw/MenuButton.h>
  23. #include <X11/Xaw/SimpleMenu.h>
  24. #include <X11/Xaw/Scrollbar.h>
  25. #include <X11/Xaw/Cardinals.h>    
  26. #include <X11/cursorfont.h>
  27. #ifdef MULTILIST
  28. #include <MultiList.h>
  29. #else
  30. #include <X11/Xaw/List.h>
  31. #endif
  32. #include "sysdefs.h"
  33. #include "xarchie.h"
  34. #include "types.h"
  35. #include "appres.h"
  36. #include "weight.h"
  37. #include "db.h"
  38. #include "actions.h"
  39. #include "display.h"
  40. #include "settings.h"
  41. #include "menu.h"
  42. #include "m-defs.h"
  43. #include "status.h"
  44. #include "browser.h"
  45. #include "selection.h"
  46. #include "file-panel.h"
  47. #include "ftp-actions.h"
  48. #include "about.h"
  49. #ifdef HELP
  50. # include "help.h"
  51. #endif
  52. #include "view-file.h"
  53. #include "username.h"
  54. #include "hostname.h"
  55. #include "tilde.h"
  56. #include "syntax.h"
  57. #include "xarchie.xbm"
  58. #include "busy.xbm"
  59.  
  60. /*    -    -    -    -    -    -    -    -    */
  61. /*
  62.  * Functions defined in this file:
  63.  */
  64. /* main() */
  65. void bye();
  66. void setBusyStatus(),setIconStatus();
  67.  
  68. static void initGraphics(),initColors(),initMenus(),initWidgets();
  69. static void initErrorHandlers(), initMisc();
  70. static void browserCallback();
  71. static void setWindowBusyStatus();
  72. static void iconifyEventHandler();
  73. #ifdef DEBUG
  74. static void xerror();
  75. #endif
  76.  
  77. /*
  78.  * Global graphics data
  79.  */
  80. Display *display;
  81. Screen *screen;
  82. Window root;
  83. Atom WM_DELETE_WINDOW,WM_PROTOCOLS,WM_STATE;
  84.  
  85. /*
  86.  * Local graphics data
  87.  */
  88. static Cursor busyCursor;
  89.  
  90. /*
  91.  * Global widget data
  92.  */
  93. XtAppContext appContext;
  94. Widget toplevel,realToplevel;
  95. Widget fileButton,settingsButton;
  96. Widget queryButton,abortButton;
  97. #ifdef HELP
  98. Widget helpButton;
  99. #endif
  100. Widget statusText;
  101. Widget browserForm;
  102. Widget browserUpButton,browserDownButton;
  103. Widget browserViewports[NUM_BROWSER_PANES];
  104. Widget browserScrollbars[NUM_BROWSER_PANES];
  105. Widget browserLists[NUM_BROWSER_PANES];
  106. Widget searchText;
  107. Widget hostText,locationText,fileText,sizeText,modesText,dateText;
  108.  
  109. /*
  110.  * Other global data
  111.  */
  112. DbEntry *db;
  113. char *program;
  114. char *tmpDirectory;
  115.  
  116. /*
  117.  * The application resources
  118.  */
  119. AppResources appResources;
  120.  
  121. /*
  122.  * Non-widget resources obtained from resource manager
  123.  */
  124. static XtResource resources[] = {
  125.     { "searchType", "SearchType", GfRSearchType, sizeof(SearchType),
  126.       XtOffset(AppResources *,searchType), XtRImmediate, (XtPointer)GfExact },
  127.     { "sortType", "SortType", GfRSortType, sizeof(SortType),
  128.       XtOffset(AppResources *,sortType), XtRImmediate, (XtPointer)GfName },
  129.     { "archieHost", "ArchieHost", XtRString, sizeof(String),
  130.       XtOffset(AppResources *,archieHost), XtRImmediate, "archie.sura.net" },
  131.     { "numHosts", "numHosts", XtRInt, sizeof(int),
  132.       XtOffset(AppResources *,numHosts), XtRImmediate, (XtPointer)1 },
  133.     { "maxHits", "MaxHits", XtRInt, sizeof(int),
  134.       XtOffset(AppResources *,maxHits), XtRImmediate, (XtPointer)99 },
  135.     { "offset", "Offset", XtRInt, sizeof(int),
  136.       XtOffset(AppResources *,offset), XtRImmediate, (XtPointer)0 },
  137.     { "timeout", "Timeout", XtRInt, sizeof(int),
  138.       XtOffset(AppResources *,timeout), XtRImmediate, (XtPointer)0 },
  139.     { "retries", "Retries", XtRInt, sizeof(int),
  140.       XtOffset(AppResources *,retries), XtRImmediate, (XtPointer)0 },
  141.     { "niceLevel", "NiceLevel", XtRInt, sizeof(int),
  142.       XtOffset(AppResources *,niceLevel), XtRImmediate, (XtPointer)0 },
  143.     { "ftpLocalDir", "FtpLocalDir", XtRString, sizeof(String),
  144.       XtOffset(AppResources *,ftpLocalDir), XtRImmediate, "" },
  145.     { "ftpType", "FtpType", XtRString, sizeof(String),
  146.       XtOffset(AppResources *,ftpType), XtRImmediate, "binary" },
  147.     { "ftpPrompt", "FtpPrompt", XtRBoolean, sizeof(Boolean),
  148.       XtOffset(AppResources *,ftpPrompt), XtRImmediate, (XtPointer)False },
  149.     { "ftpTrace", "FtpTrace", XtRBoolean, sizeof(Boolean),
  150.       XtOffset(AppResources *,ftpTrace), XtRImmediate, (XtPointer)False },
  151.     { "ftpStrip", "FtpStrip", XtRBoolean, sizeof(Boolean),
  152.       XtOffset(AppResources *,ftpStrip), XtRImmediate, (XtPointer)True },
  153.     { "ftpMailAddress", "FtpMailAddress", XtRString, sizeof(String),
  154.       XtOffset(AppResources *,ftpMailAddress), XtRImmediate, "%s@%s" },
  155.     { "debugLevel", "DebugLevel", XtRInt, sizeof(int),
  156.       XtOffset(AppResources *,debugLevel), XtRImmediate, (XtPointer)0 },
  157.     { "fileWriteOnePerLine", "FileWriteOnePerLine", XtRBoolean,sizeof(Boolean),
  158.       XtOffset(AppResources *,fileWriteOnePerLine), XtRImmediate,
  159.                               (XtPointer)False },
  160.     { "xarchieFont", "Font", XtRFontStruct, sizeof(XFontStruct*),
  161.       XtOffset(AppResources *,xarchieFont), XtRString, XtDefaultFont },
  162.     { "xarchieBoldFont", "Font", XtRFontStruct, sizeof(XFontStruct*),
  163.       XtOffset(AppResources *,xarchieBoldFont), XtRString, XtDefaultFont },
  164.     { "hostWeights", "HostWeights", XtRString, sizeof(String),
  165.       XtOffset(AppResources *,hostWeights), XtRImmediate, NULL },
  166.     { "autoScroll", "AutoScroll", XtRBoolean, sizeof(Boolean),
  167.       XtOffset(AppResources *,autoScroll), XtRImmediate, (XtPointer)True },
  168.     { "pasteBuffer", "PasteBuffer", XtRBoolean, sizeof(Boolean),
  169.       XtOffset(AppResources *,pasteBuffer), XtRImmediate, (XtPointer)True },
  170.     { "visualType", "VisualType", XtRString, sizeof(String),
  171.       XtOffset(AppResources *,visualType), XtRImmediate, (XtPointer)"" },
  172.     { "defaultIcon", "Icon", XtRBitmap, sizeof(Pixmap),
  173.       XtOffset(AppResources *,defaultIcon), XtRImmediate, None },
  174.     { "busyIcon", "Icon", XtRBitmap, sizeof(Pixmap),
  175.       XtOffset(AppResources *,busyIcon), XtRImmediate, None },
  176. };
  177.  
  178. /*
  179.  * Non-widget resources set on command line.
  180.  */
  181. static XrmOptionDescRec options[] = {
  182.     { "-search",  ".searchType", XrmoptionSepArg, (XtPointer)"exact" },
  183.     { "-e",      ".searchType", XrmoptionNoArg,  (XtPointer)"exact" },
  184.     { "-s",      ".searchType", XrmoptionNoArg,  (XtPointer)"substr" },
  185.     { "-c",      ".searchType", XrmoptionNoArg,  (XtPointer)"subcase" },
  186.     { "-r",      ".searchType", XrmoptionNoArg,  (XtPointer)"regexp" },
  187.     { "-es",      ".searchType", XrmoptionNoArg,  (XtPointer)"exactSubstr" },
  188.     { "-ec",      ".searchType", XrmoptionNoArg,  (XtPointer)"exactSubcase" },
  189.     { "-er",      ".searchType", XrmoptionNoArg,  (XtPointer)"exactRegexp" },
  190.     { "-sort",      ".sortType",     XrmoptionSepArg, (XtPointer)"name" },
  191.     { "-t",      ".sortType",     XrmoptionNoArg,  (XtPointer)"date" },
  192.     { "-w",      ".sortType",     XrmoptionNoArg,  (XtPointer)"weight" },
  193.     { "-host",      ".archieHost", XrmoptionSepArg,
  194.                     (XtPointer)"archie.sura.ca" },
  195.     { "-maxhits", ".maxHits",     XrmoptionSepArg, (XtPointer)"99" },
  196.     { "-offset",  ".offset",     XrmoptionSepArg, (XtPointer)"0" },
  197.     { "-nice",      ".niceLevel",     XrmoptionSepArg, (XtPointer)"0" },
  198.     { "-N",      ".niceLevel",     XrmoptionSepArg, (XtPointer)"0" },
  199.     { "-debug",      ".debugLevel", XrmoptionSepArg, (XtPointer)"1" },
  200.     { "-D",      ".debugLevel", XrmoptionSepArg, (XtPointer)"1" },
  201.     { "-noscroll",".autoScroll", XrmoptionNoArg,  (XtPointer)"False" },
  202.     { "-mono",      ".visualType", XrmoptionNoArg,  (XtPointer)"mono" },
  203.     { "-gray",      ".visualType", XrmoptionNoArg,  (XtPointer)"gray" },
  204.     { "-color",      ".visualType", XrmoptionNoArg,  (XtPointer)"color" },
  205. };
  206.  
  207. /*
  208.  * Widget and non-widget resources if the application defaults
  209.  * file can't be found.
  210.  * Generated automatically from Xarchie.ad by "ad2c".
  211.  * Comment out the include line (but not the NULL) if you don't want
  212.  * any resources compiled in.
  213.  */
  214. static String fallbackResources[] = {
  215. #include "Xarchie.ad.h"
  216.     NULL
  217. };
  218.  
  219. /*    -    -    -    -    -    -    -    -    */
  220.  
  221. main(argc,argv)
  222. int argc;
  223. char **argv;
  224. {
  225.     program = argv[0];
  226.     /* Init display and application context, other globals, parse args */
  227.     initGraphics(&argc,argv);
  228.     if (argc > 1) {
  229.     syntax(argc,argv);
  230.     bye(1);
  231.     }
  232.     /* Init other non-widget stuff */
  233.     initErrorHandlers();
  234.     initColors();
  235.     initActions();
  236.     initHostWeights();
  237.     /* Then init the menus so they can be found for other widgets */
  238.     initMenus();
  239.     /* Then the main panel widgets */
  240.     initWidgets();
  241.     /* Now we realize so the toplevel window is available */
  242.     XtRealizeWidget(realToplevel);
  243.     /* Other initializations that need to go now */
  244.     initSettings();
  245. #ifdef HELP
  246.     initHelpPanel();
  247. #endif
  248.     initMisc();
  249.     /* Enable WM_DELETE_WINDOW processing */
  250.     (void)XSetWMProtocols(display,XtWindow(realToplevel),&WM_DELETE_WINDOW,1);
  251.     status0("Ready");
  252.     /* Init the data structure for responses */
  253.     db = newEntry();
  254.     resetBrowser();
  255.     setBrowserState(BROWSER_READY);
  256.     /* Do it */
  257.     XtAppMainLoop(appContext);
  258.     /*NOTREACHED*/
  259. }
  260.  
  261. void
  262. bye(ret)
  263. int ret;
  264. {
  265.     XtDestroyApplicationContext(appContext);
  266. #ifdef CUTCP
  267.     netshut();
  268. #endif
  269.     exit(ret);
  270. }
  271.  
  272. /*    -    -    -    -    -    -    -    -    */
  273. /* Initialization routines */
  274.  
  275. static void
  276. initGraphics(argcp,argv)
  277. int *argcp;
  278. char **argv;
  279. {
  280.     /* Some systems want (Cardinal*), others want (int*) for argcp. */
  281.     realToplevel = toplevel =
  282.     XtAppInitialize(&appContext,"Xarchie",options,XtNumber(options),
  283.             (Cardinal *)argcp,argv,fallbackResources,NULL,ZERO);
  284.     /*
  285.      * Set graphics globals
  286.      */
  287.     display = XtDisplay(realToplevel);
  288.     screen = XtScreen(realToplevel);
  289.     root = RootWindowOfScreen(screen);
  290.     busyCursor = XCreateFontCursor(display,XC_watch);
  291.     WM_PROTOCOLS = XInternAtom(display,"WM_PROTOCOLS",False);
  292.     WM_DELETE_WINDOW = XInternAtom(display,"WM_DELETE_WINDOW",False);
  293.     WM_STATE = XInternAtom(display,"WM_STATE",False);
  294.     /*
  295.      * Set up the resource converters (needs globals)
  296.      */
  297.     initConverters(appContext);
  298.     /*
  299.      * Get non-widget resources
  300.      */
  301.     XtGetApplicationResources(realToplevel,(XtPointer)&appResources,
  302.                   resources,XtNumber(resources),NULL,ZERO);
  303.     /*
  304.      * Realloc these right away so we can free/realloc them later
  305.      */
  306.     appResources.archieHost = XtNewString(appResources.archieHost);
  307.     appResources.ftpLocalDir = XtNewString(appResources.ftpLocalDir);
  308.     appResources.ftpType = XtNewString(appResources.ftpType);
  309.     appResources.hostWeights = XtNewString(appResources.hostWeights);
  310.     /*
  311.      * Catch iconify/deiconify so we can do children also
  312.      */
  313.     XtAddEventHandler(realToplevel,PropertyChangeMask,False,
  314.               iconifyEventHandler,NULL);
  315. #ifdef DEBUG
  316.     XSetErrorHandler(xerror);
  317.     XSynchronize(display,True);
  318. #endif
  319. }
  320.  
  321. /*
  322.  * initColors: To allow resources to be specfied separately for color
  323.  *    and mono displays, we add a dummy Form widget below realToplevel
  324.  *    in appropriate circumstances.
  325.  *      This means that:
  326.  *      - realToplevel gets realized
  327.  *      - toplevel gets used as parent of children
  328.  */
  329. #define ADDTOPLEVEL(NAME) \
  330.     toplevel = XtCreateManagedWidget(NAME,formWidgetClass, \
  331.                      realToplevel,NULL,0);
  332. static void
  333. initColors()
  334. {
  335.     Visual *visual;
  336.  
  337.     /* The default is no extra widget (ie. mono) */
  338.     toplevel = realToplevel;
  339.     /* See if the user specified a type */
  340.     if (strcmp(appResources.visualType,"mono") == 0) {
  341.     return;
  342.     } else if (strcmp(appResources.visualType,"color") == 0) {
  343.     ADDTOPLEVEL("color");
  344.     return;
  345.     } else if (strcmp(appResources.visualType,"gray") == 0) {
  346.     ADDTOPLEVEL("gray");
  347.     return;
  348.     }
  349.     /* Otherwise we try to figure it out */
  350.     if ((visual=XDefaultVisualOfScreen(screen)) == NULL) {
  351.     fprintf(stderr,"%s: can't get info about visual!\n",program);
  352.     return;
  353.     }
  354.     if (visual->map_entries > 2) {
  355.     switch (visual->class) {
  356.       case StaticColor:
  357.       case PseudoColor:
  358.       case TrueColor:
  359.       case DirectColor:
  360.         ADDTOPLEVEL("color");
  361.         break;
  362.       case StaticGray:
  363.       case GrayScale:
  364.         ADDTOPLEVEL("gray");
  365.         break;
  366.       default:
  367.         toplevel = realToplevel;
  368.     }
  369.     } else {
  370.     toplevel = realToplevel;
  371.     }
  372. }
  373.  
  374. /*
  375.  * initMenus: Call all the menu initialization routines
  376.  */
  377. static void
  378. initMenus()
  379. {
  380.     initMenuCreator();        /* must be first */
  381.     initFileMenu();
  382.     initQueryMenu();
  383.     initSettingsMenu();
  384.     initFilePanelMenu();
  385. }
  386.  
  387. /*
  388.  * initWidgets: Initialize the widgets and set globals variables.
  389.  */
  390. static void
  391. initWidgets()
  392. {
  393.     Widget outerPaned,buttonForm,browserPaned;
  394.     Widget stringForm;
  395.     char name[32];
  396.     int i;
  397.  
  398.     outerPaned = XtCreateManagedWidget("outerPaned",panedWidgetClass,
  399.                        toplevel,NULL,0);
  400.     /* Button Form */
  401.     buttonForm = XtCreateManagedWidget("buttonForm",formWidgetClass,
  402.                        outerPaned,NULL,0);
  403.     fileButton = XtCreateManagedWidget("fileButton",menuButtonWidgetClass,
  404.                        buttonForm,NULL,0);
  405.     settingsButton = XtCreateManagedWidget("settingsButton",
  406.                        menuButtonWidgetClass,
  407.                        buttonForm,NULL,0);
  408.     queryButton = XtCreateManagedWidget("queryButton",
  409.                     menuButtonWidgetClass,
  410.                     buttonForm,NULL,0);
  411.     abortButton = XtCreateManagedWidget("abortButton",
  412.                     commandWidgetClass,
  413.                     buttonForm,NULL,0);
  414.     XtSetSensitive(abortButton,False);
  415. #ifdef HELP
  416.     helpButton = XtCreateManagedWidget("helpButton",commandWidgetClass,
  417.                        buttonForm,NULL,0);
  418. #endif
  419.     (void)XtCreateManagedWidget("statusLabel",labelWidgetClass,
  420.                 buttonForm,NULL,0);
  421.     statusText = XtCreateManagedWidget("statusText",asciiTextWidgetClass,
  422.                        buttonForm,NULL,0);
  423.     /* Browser */
  424.     browserForm = XtCreateManagedWidget("browserForm",formWidgetClass,
  425.                     outerPaned,NULL,0);
  426.     browserUpButton = XtCreateManagedWidget("browserUpButton",
  427.                         commandWidgetClass,
  428.                         browserForm,NULL,0);
  429.     browserDownButton = XtCreateManagedWidget("browserDownButton",
  430.                           commandWidgetClass,
  431.                           browserForm,NULL,0);
  432.     browserPaned = XtCreateManagedWidget("browserPaned",panedWidgetClass,
  433.                      browserForm,NULL,0);
  434.     for (i=0; i < NUM_BROWSER_PANES; i++) {
  435.     sprintf(name,"browserViewport%d",i);
  436.     browserViewports[i] = XtCreateManagedWidget(name,viewportWidgetClass,
  437.                             browserPaned,NULL,0);
  438.     browserScrollbars[i] = XtNameToWidget(browserViewports[i],"vertical");
  439.     sprintf(name,"browserList%d",i);
  440. #ifdef MULTILIST
  441.     browserLists[i] = XtCreateManagedWidget(name,xfwfMultiListWidgetClass,
  442.                         browserViewports[i],NULL,0);
  443. #else
  444.     browserLists[i] = XtCreateManagedWidget(name,listWidgetClass,
  445.                         browserViewports[i],NULL,0);
  446. #endif
  447.     clearBrowserPane(i);
  448.     XtAddCallback(browserLists[i],XtNcallback,
  449.               browserCallback,(XtPointer)i);
  450.     }
  451.     /* String Form */
  452.     stringForm = XtCreateManagedWidget("stringForm",formWidgetClass,
  453.                        outerPaned,NULL,0);
  454.     (void)XtCreateManagedWidget("searchLabel",labelWidgetClass,
  455.                 stringForm,NULL,0);
  456.     searchText = XtCreateManagedWidget("searchText",asciiTextWidgetClass,
  457.                        stringForm,NULL,0);
  458.     (void)XtCreateManagedWidget("hostLabel",labelWidgetClass,
  459.                 stringForm,NULL,0);
  460.     hostText = XtCreateManagedWidget("hostText",asciiTextWidgetClass,
  461.                      stringForm,NULL,0);
  462.     (void)XtCreateManagedWidget("locationLabel",labelWidgetClass,
  463.                 stringForm,NULL,0);
  464.     locationText = XtCreateManagedWidget("locationText",asciiTextWidgetClass,
  465.                      stringForm,NULL,0);
  466.     (void)XtCreateManagedWidget("fileLabel",labelWidgetClass,
  467.                 stringForm,NULL,0);
  468.     fileText = XtCreateManagedWidget("fileText",asciiTextWidgetClass,
  469.                      stringForm,NULL,0);
  470.     (void)XtCreateManagedWidget("sizeLabel",labelWidgetClass,
  471.                 stringForm,NULL,0);
  472.     sizeText = XtCreateManagedWidget("sizeText",asciiTextWidgetClass,
  473.                      stringForm,NULL,0);
  474.     (void)XtCreateManagedWidget("modesLabel",labelWidgetClass,
  475.                 stringForm,NULL,0);
  476.     modesText = XtCreateManagedWidget("modesText",asciiTextWidgetClass,
  477.                       stringForm,NULL,0);
  478.     (void)XtCreateManagedWidget("dateLabel",labelWidgetClass,
  479.                 stringForm,NULL,0);
  480.     dateText = XtCreateManagedWidget("dateText",asciiTextWidgetClass,
  481.                      stringForm,NULL,0);
  482. }
  483.  
  484. static void
  485. initMisc()
  486. {
  487.     char *user,*host,*addr;
  488.  
  489.     if ((tmpDirectory=getenv("TMPDIR")) == NULL) {
  490.     tmpDirectory = "/tmp";
  491.     }
  492.     user = GetUsername();
  493.     host = GetHostname();
  494.     addr = XtMalloc(strlen(user)+
  495.             strlen(host)+strlen(appResources.ftpMailAddress));
  496.     sprintf(addr,appResources.ftpMailAddress,user,host);
  497.     appResources.ftpMailAddress = addr;
  498.     /* Do initial tilde expansion if needed */
  499.     if (appResources.ftpLocalDir && *(appResources.ftpLocalDir) == '~') {
  500.     appResources.ftpLocalDir =
  501.         XtNewString(tildeExpand(appResources.ftpLocalDir));
  502.     }
  503.     /* Use the default icons unless overridden */
  504.     if (appResources.defaultIcon == None) {
  505.     appResources.defaultIcon =
  506.         XCreateBitmapFromData(display,root,xarchie_bits,
  507.                   xarchie_width,xarchie_height);
  508.     }
  509.     if (appResources.busyIcon == None) {
  510.     appResources.busyIcon =
  511.         XCreateBitmapFromData(display,root,busy_bits,
  512.                   busy_width,busy_height);
  513.     }
  514.     /* Tell the world about the initial icons */
  515.     setIconStatus(0);
  516. }
  517.  
  518. /*    -    -    -    -    -    -    -    -    */
  519. /* The following functions attempt to provide information in the event of
  520.  * a crash. If you have trouble compiling them because of UNIX-isms in
  521.  * the signal handlers, then add -DDONT_CATCH_ERRORS to the definition
  522.  * of DEFINES in the Imakefile and re-make (or just #define it here).
  523.  */
  524. #ifndef DONT_CATCH_ERRORS
  525. #include <signal.h>
  526. static void crashHandler();
  527. #endif /* DONT_CATCH_ERRORS */
  528.  
  529. static void
  530. initErrorHandlers()
  531. {
  532. #ifndef DONT_CATCH_ERRORS
  533.     signal(SIGBUS,crashHandler);
  534.     signal(SIGSEGV,crashHandler);
  535. #endif /* DONT_CATCH_ERRORS */
  536. }
  537.  
  538. #ifndef DONT_CATCH_ERRORS
  539. static void
  540. crashHandler(sig)
  541. int sig;
  542. {
  543.     char *s;
  544.  
  545.     switch (sig) {
  546.     case SIGBUS: s = "SIGBUS"; break;
  547.     case SIGSEGV: s = "SIGSEGV"; break;
  548.     default: s = "UNKNOWN";
  549.     }
  550.     fprintf(stderr,"%s: caught a %s signal!\n",program,s);
  551.     fprintf(stderr,"If you want to report an error, please indicate your hardware type,\n");
  552.     fprintf(stderr,"operating system, compiler, and your version of X and include a\n");
  553.     fprintf(stderr,"backtrace. Thanks.\n");
  554.     abort();
  555. }
  556.  
  557. #endif /* DONT_CATCH_ERRORS */
  558.  
  559. #ifdef DEBUG
  560. /*
  561.  * Override default X error handler to force an abort to debugger
  562.  */
  563. static void
  564. xerror(display,event)
  565. Display *display;
  566. XErrorEvent *event;
  567. {
  568.     char buf[256];
  569.  
  570.     XGetErrorText(display,event->error_code,buf,256);
  571.     printf("XERROR: %d: %s\n",event->error_code,buf);
  572.     abort();
  573. }
  574. #endif
  575.  
  576. /*    -    -    -    -    -    -    -    -    */
  577. /* Callback procedures */
  578.  
  579. /*ARGSUSED*/
  580. static void
  581. browserCallback(w,client_data,call_data)
  582. Widget w;
  583. XtPointer client_data;    /* pane */
  584. XtPointer call_data;    /* returnStruct */
  585. {
  586.     int pane = (int)client_data;
  587. #ifdef MULTILIST
  588. #ifdef DEBUG
  589.     static char *actions[] = { "NOTHING","HIGHLIGHT","UNHIGHLIGHT","STATUS" };
  590.     int i;
  591. #endif
  592.     XfwfMultiListReturnStruct *ret = (XfwfMultiListReturnStruct*)call_data;
  593.  
  594. #ifdef DEBUG
  595.     printf("Callback: %s, item %d\n",actions[ret->action],ret->item);
  596.     printf("  num_selected = %d\n",ret->num_selected);
  597.     printf("  selected_items[] = ");
  598.     for (i = 0; i < ret->num_selected; i++) {
  599.     printf("%d ",ret->selected_items[i]);
  600.     }
  601.     if (ret->num_selected == 0) printf("None");
  602.     printf("\n");
  603. #endif /* DEBUG */
  604.     switch (ret->action) {
  605.       case XfwfMultiListActionHighlight:
  606.     /* Anything selected? */
  607.     if (ret->item != -1) {
  608.         /* If just one thing selected, then we came here from Select() */
  609.         if (ret->num_selected == 1)
  610.         resetSelectionsForPane(pane);
  611.         selectBrowserItem(pane,ret->item);
  612.     }
  613.     break;
  614.       case XfwfMultiListActionUnhighlight:
  615.     if (ret->item == -1)
  616.         resetSelectionsForPane(pane);
  617.     else
  618.         unselectBrowserItem(pane,ret->item);
  619.     break;
  620.     }
  621. #else /* !MULTILIST */
  622.     XawListReturnStruct *ret = (XawListReturnStruct*)call_data;
  623.  
  624.     resetSelectionsForPane(pane);
  625.     selectBrowserItem(pane,ret->list_index);
  626. #endif /* !MULTILIST */
  627. }
  628.  
  629. /*    -    -    -    -    -    -    -    -    */
  630. /* Misc. routines */
  631.  
  632. void
  633. setBusyStatus(state)
  634. Boolean state;
  635. {
  636.     setWindowBusyStatus(XtWindow(realToplevel),state);
  637. }
  638.  
  639. static void
  640. setWindowBusyStatus(window,state)
  641. Window window;
  642. Boolean state;
  643. {
  644.     Window root,parent,*children;
  645.     unsigned int numChildren;
  646.     int i;
  647.  
  648.     /* Do the window */
  649.     if (state)
  650.     XDefineCursor(display,window,busyCursor);
  651.     else
  652.     XUndefineCursor(display,window);
  653.     /* And all the children... */
  654.     if (XQueryTree(display,window,&root,&parent,&children,&numChildren) != 0) {
  655.     for (i=0; i < numChildren; i++) {
  656.         setWindowBusyStatus(*(children+i),state);
  657.     }
  658.     if (numChildren > 0)
  659.         XFree((char *)children);
  660.     }
  661. }
  662.         
  663. /*    -    -    -    -    -    -    -    -    */
  664.  
  665. /*ARGSUSED*/
  666. static void
  667. iconifyEventHandler(w,client_data,event,cont)
  668. Widget w;
  669. XtPointer client_data;
  670. XEvent *event;
  671. Boolean *cont;
  672. {
  673.     int state;
  674.  
  675.     if (event->xproperty.state == PropertyNewValue &&
  676.     event->xproperty.atom == WM_STATE) {
  677.     Atom actual_type;
  678.     int actual_format;
  679.     unsigned long nitems = 0, bytes_after = 0;
  680.     unsigned char* data = NULL;
  681.  
  682.     if (XGetWindowProperty(display,XtWindow(realToplevel),
  683.                    WM_STATE,0,2,False,AnyPropertyType,
  684.                    &actual_type,&actual_format,
  685.                    &nitems,&bytes_after,&data) == Success) {
  686.         state = *(int *)data;
  687.         setSettingsShellState(state);
  688.         setFileShellState(state);
  689. #ifdef HELP
  690.         setHelpShellState(state);
  691. #endif
  692.         setAboutShellState(state);
  693.         setFtpTraceShellState(state);
  694.         XFree((char *)data);
  695.     }
  696.     }
  697. }
  698.  
  699. void
  700. setIconStatus(state)
  701. Boolean state;
  702. {
  703.     Pixmap pixmap;
  704.     char *name;
  705.     Arg args[2];
  706.  
  707.     if (state == True) {
  708.     pixmap = appResources.busyIcon;
  709.     name = "xarchie:busy";
  710.     } else {
  711.     pixmap = appResources.defaultIcon;
  712.     name = "xarchie";
  713.     }
  714.     XtSetArg(args[0],XtNiconName,name);
  715.     XtSetArg(args[1],XtNiconPixmap,pixmap);
  716.     XtSetValues(realToplevel,args,2);
  717. }
  718.